

/***
 * @Date            : 2024-12-22 22:55:56
 * @Author          : AnimateX(Baron)
 * @LastEditors     : AnimateX(Baron)
 * @LastEditTime    : 2024-12-22 22:55:59
 * @FilePath        : /include/camera.h
 * @CopyRight       : Copyright (c) 2025 AnimateX. All rights reserved.
 * @Description     :
 */
#include <string>
#include <cstdint>
#include <vector>


namespace rc {
    struct Config {
        std::string     devicePath;
        int             width;
        int             height;
        uint32_t        pixelFormat;
        int             fps;
    };

    struct Buffer {
        void*           start;
        size_t          length;
    };

    class V4LCamera {
    public:
        explicit V4LCamera(const std::string& devCardName)
            : mCamCardName(devCardName)
            , mCamFd(-1)
            , mIsStreaming(false)
            , mReconnectAttempts(0) { }

        ~V4LCamera() {
            closeDevice();
        }

        bool initialize(int width, int height, uint32_t pixelFmt, int fps);
        bool startStreaming();
        bool captureFrame(std::vector<uint8_t>& frameData);
        bool stopStreaming();

        int getCameraFd() const { return mCamFd; }
        const Config& getCamConfigInfo() const { return mCamConfig; }

        // disconnect recovery
        bool reconnect();
        bool isConnected() const { return mCamFd != -1; }

    private:
        bool setFormat();
        bool setFrameRate();
        bool initMmap();
        bool findV4l2CameraDevicePath();

        void closeDevice();
        bool openDevice();
        bool checkDeviceStatus();

        std::string         mCamCardName;
        Config              mCamConfig;
        int                 mCamFd;
        std::vector<Buffer> mBuffers;
        bool                mIsStreaming;

        static const int    MAX_RECONNECT_ATTEMPTS;
        int                 mReconnectAttempts;
    };

}
